--- /dev/null
+/* GdkQuartzWindow.m
+ *
+ * Copyright (C) 2005-2007 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import "GdkQuartzNSWindow.h"
+#include "gdkquartzwindow.h"
+#include "gdkdnd-quartz.h"
+#include "gdkprivate-quartz.h"
+
+@implementation GdkQuartzNSWindow
+
+-(BOOL)windowShouldClose:(id)sender
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+ GdkEvent *event;
+
+ event = gdk_event_new (GDK_DELETE);
+
+ event->any.window = g_object_ref (window);
+ event->any.send_event = FALSE;
+
+ _gdk_event_queue_append (gdk_display_get_default (), event);
+
+ return NO;
+}
+
+-(void)windowWillMiniaturize:(NSNotification *)aNotification
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+
+ _gdk_quartz_window_detach_from_parent (window);
+}
+
+-(void)windowDidMiniaturize:(NSNotification *)aNotification
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+
+ gdk_synthesize_window_state (window, 0,
+ GDK_WINDOW_STATE_ICONIFIED);
+}
+
+-(void)windowDidDeminiaturize:(NSNotification *)aNotification
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+
+ _gdk_quartz_window_attach_to_parent (window);
+
+ gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0);
+}
+
+-(void)windowDidBecomeKey:(NSNotification *)aNotification
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+
+ _gdk_quartz_events_update_focus_window (window, TRUE);
+}
+
+-(void)windowDidResignKey:(NSNotification *)aNotification
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+
+ _gdk_quartz_events_update_focus_window (window, FALSE);
+}
+
+-(void)windowDidBecomeMain:(NSNotification *)aNotification
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+
+ if (![self isVisible])
+ {
+ /* Note: This is a hack needed because for unknown reasons, hidden
+ * windows get shown when clicking the dock icon when the application
+ * is not already active.
+ */
+ [self orderOut:nil];
+ return;
+ }
+
+ _gdk_quartz_window_did_become_main (window);
+}
+
+-(void)windowDidResignMain:(NSNotification *)aNotification
+{
+ GdkWindow *window;
+
+ window = [[self contentView] gdkWindow];
+ _gdk_quartz_window_did_resign_main (window);
+}
+
+/* Used in combination with NSLeftMouseUp in sendEvent to keep track
+ * of when the window is being moved with the mouse.
+ */
+-(void)windowWillMove:(NSNotification *)aNotification
+{
+ inMove = YES;
+}
+
+-(void)sendEvent:(NSEvent *)event
+{
+ switch ([event type])
+ {
+ case NSLeftMouseUp:
+ inManualMove = NO;
+ inManualResize = NO;
+ inMove = NO;
+ break;
+
+ case NSLeftMouseDragged:
+ if ([self trackManualMove] || [self trackManualResize])
+ return;
+ break;
+
+ default:
+ break;
+ }
+
+ [super sendEvent:event];
+}
+
+-(BOOL)isInMove
+{
+ return inMove;
+}
+
+-(void)windowDidMove:(NSNotification *)aNotification
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+ GdkEvent *event;
+
+ _gdk_quartz_window_update_position (window);
+
+ /* Synthesize a configure event */
+ event = gdk_event_new (GDK_CONFIGURE);
+ event->configure.window = g_object_ref (window);
+ event->configure.x = window->x;
+ event->configure.y = window->y;
+ event->configure.width = window->width;
+ event->configure.height = window->height;
+
+ _gdk_event_queue_append (gdk_display_get_default (), event);
+}
+
+-(void)windowDidResize:(NSNotification *)aNotification
+{
+ NSRect content_rect = [self contentRectForFrameRect:[self frame]];
+ GdkWindow *window = [[self contentView] gdkWindow];
+ GdkEvent *event;
+
+ window->width = content_rect.size.width;
+ window->height = content_rect.size.height;
+
+ [[self contentView] setFrame:NSMakeRect (0, 0, window->width, window->height)];
+
+ _gdk_window_update_size (window);
+
+ /* Synthesize a configure event */
+ event = gdk_event_new (GDK_CONFIGURE);
+ event->configure.window = g_object_ref (window);
+ event->configure.x = window->x;
+ event->configure.y = window->y;
+ event->configure.width = window->width;
+ event->configure.height = window->height;
+
+ _gdk_event_queue_append (gdk_display_get_default (), event);
+}
+
+-(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen
+{
+ self = [super initWithContentRect:contentRect
+ styleMask:styleMask
+ backing:backingType
+ defer:flag
+ screen:screen];
+
+ [self setAcceptsMouseMovedEvents:YES];
+ [self setDelegate:self];
+ [self setReleasedWhenClosed:YES];
+
+ return self;
+}
+
+-(BOOL)canBecomeMainWindow
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
+
+ switch (impl->type_hint)
+ {
+ case GDK_WINDOW_TYPE_HINT_NORMAL:
+ case GDK_WINDOW_TYPE_HINT_DIALOG:
+ return YES;
+
+ case GDK_WINDOW_TYPE_HINT_MENU:
+ case GDK_WINDOW_TYPE_HINT_TOOLBAR:
+ case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
+ case GDK_WINDOW_TYPE_HINT_UTILITY:
+ case GDK_WINDOW_TYPE_HINT_DOCK:
+ case GDK_WINDOW_TYPE_HINT_DESKTOP:
+ case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
+ case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
+ case GDK_WINDOW_TYPE_HINT_TOOLTIP:
+ case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
+ case GDK_WINDOW_TYPE_HINT_COMBO:
+ case GDK_WINDOW_TYPE_HINT_DND:
+ return NO;
+ }
+
+ return YES;
+}
+
+-(BOOL)canBecomeKeyWindow
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
+
+ if (!window->accept_focus)
+ return NO;
+
+ /* Popup windows should not be able to get focused in the window
+ * manager sense, it's only handled through grabs.
+ */
+ if (window->window_type == GDK_WINDOW_TEMP)
+ return NO;
+
+ switch (impl->type_hint)
+ {
+ case GDK_WINDOW_TYPE_HINT_NORMAL:
+ case GDK_WINDOW_TYPE_HINT_DIALOG:
+ case GDK_WINDOW_TYPE_HINT_MENU:
+ case GDK_WINDOW_TYPE_HINT_TOOLBAR:
+ case GDK_WINDOW_TYPE_HINT_UTILITY:
+ case GDK_WINDOW_TYPE_HINT_DOCK:
+ case GDK_WINDOW_TYPE_HINT_DESKTOP:
+ case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
+ case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
+ case GDK_WINDOW_TYPE_HINT_COMBO:
+ return YES;
+
+ case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
+ case GDK_WINDOW_TYPE_HINT_TOOLTIP:
+ case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
+ case GDK_WINDOW_TYPE_HINT_DND:
+ return NO;
+ }
+
+ return YES;
+}
+
+- (void)showAndMakeKey:(BOOL)makeKey
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
+
+ inShowOrHide = YES;
+
+ if (makeKey)
+ [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
+ else
+ [impl->toplevel orderFront:nil];
+
+ inShowOrHide = NO;
+}
+
+- (void)hide
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
+
+ inShowOrHide = YES;
+ [impl->toplevel orderOut:nil];
+ inShowOrHide = NO;
+}
+
+- (BOOL)trackManualMove
+{
+ NSPoint currentLocation;
+ NSPoint newOrigin;
+ NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
+ NSRect windowFrame = [self frame];
+
+ if (!inManualMove)
+ return NO;
+
+ currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
+ newOrigin.x = currentLocation.x - initialMoveLocation.x;
+ newOrigin.y = currentLocation.y - initialMoveLocation.y;
+
+ /* Clamp vertical position to below the menu bar. */
+ if (newOrigin.y + windowFrame.size.height > screenFrame.origin.y + screenFrame.size.height)
+ newOrigin.y = screenFrame.origin.y + screenFrame.size.height - windowFrame.size.height;
+
+ [self setFrameOrigin:newOrigin];
+
+ return YES;
+}
+
+-(void)beginManualMove
+{
+ NSRect frame = [self frame];
+
+ if (inMove || inManualMove || inManualResize)
+ return;
+
+ inManualMove = YES;
+
+ initialMoveLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
+ initialMoveLocation.x -= frame.origin.x;
+ initialMoveLocation.y -= frame.origin.y;
+}
+
+- (BOOL)trackManualResize
+{
+ NSPoint currentLocation;
+ NSRect newFrame;
+ float dx, dy;
+ NSSize min_size;
+
+ if (!inManualResize || inTrackManualResize)
+ return NO;
+
+ inTrackManualResize = YES;
+
+ currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
+ currentLocation.x -= initialResizeFrame.origin.x;
+ currentLocation.y -= initialResizeFrame.origin.y;
+
+ dx = currentLocation.x - initialResizeLocation.x;
+ dy = -(currentLocation.y - initialResizeLocation.y);
+
+ newFrame = initialResizeFrame;
+ newFrame.size.width = initialResizeFrame.size.width + dx;
+ newFrame.size.height = initialResizeFrame.size.height + dy;
+
+ min_size = [self contentMinSize];
+ if (newFrame.size.width < min_size.width)
+ newFrame.size.width = min_size.width;
+ if (newFrame.size.height < min_size.height)
+ newFrame.size.height = min_size.height;
+
+ /* We could also apply aspect ratio:
+ newFrame.size.height = newFrame.size.width / [self aspectRatio].width * [self aspectRatio].height;
+ */
+
+ dy = newFrame.size.height - initialResizeFrame.size.height;
+
+ newFrame.origin.x = initialResizeFrame.origin.x;
+ newFrame.origin.y = initialResizeFrame.origin.y - dy;
+
+ [self setFrame:newFrame display:YES];
+
+ /* Let the resizing be handled by GTK+. */
+ if (g_main_context_pending (NULL))
+ g_main_context_iteration (NULL, FALSE);
+
+ inTrackManualResize = NO;
+
+ return YES;
+}
+
+-(void)beginManualResize
+{
+ if (inMove || inManualMove || inManualResize)
+ return;
+
+ inManualResize = YES;
+
+ initialResizeFrame = [self frame];
+ initialResizeLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
+ initialResizeLocation.x -= initialResizeFrame.origin.x;
+ initialResizeLocation.y -= initialResizeFrame.origin.y;
+}
+
+
+
+static GdkDragContext *current_context = NULL;
+
+static GdkDragAction
+drag_operation_to_drag_action (NSDragOperation operation)
+{
+ GdkDragAction result = 0;
+
+ /* GDK and Quartz drag operations do not map 1:1.
+ * This mapping represents about the best that we
+ * can come up.
+ *
+ * Note that NSDragOperationPrivate and GDK_ACTION_PRIVATE
+ * have almost opposite meanings: the GDK one means that the
+ * destination is solely responsible for the action; the Quartz
+ * one means that the source and destination will agree
+ * privately on the action. NSOperationGeneric is close in meaning
+ * to GDK_ACTION_PRIVATE but there is a problem: it will be
+ * sent for any ordinary drag, and likely not understood
+ * by any intra-widget drag (since the source & dest are the
+ * same).
+ */
+
+ if (operation & NSDragOperationGeneric)
+ result |= GDK_ACTION_MOVE;
+ if (operation & NSDragOperationCopy)
+ result |= GDK_ACTION_COPY;
+ if (operation & NSDragOperationMove)
+ result |= GDK_ACTION_MOVE;
+ if (operation & NSDragOperationLink)
+ result |= GDK_ACTION_LINK;
+
+ return result;
+}
+
+static NSDragOperation
+drag_action_to_drag_operation (GdkDragAction action)
+{
+ NSDragOperation result = 0;
+
+ if (action & GDK_ACTION_COPY)
+ result |= NSDragOperationCopy;
+ if (action & GDK_ACTION_LINK)
+ result |= NSDragOperationLink;
+ if (action & GDK_ACTION_MOVE)
+ result |= NSDragOperationMove;
+
+ return result;
+}
+
+static void
+update_context_from_dragging_info (id <NSDraggingInfo> sender)
+{
+ g_assert (current_context != NULL);
+
+ GDK_QUARTZ_DRAG_CONTEXT (current_context)->dragging_info = sender;
+ current_context->suggested_action = drag_operation_to_drag_action ([sender draggingSourceOperationMask]);
+ current_context->actions = current_context->suggested_action;
+}
+
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+{
+ GdkDeviceManager *device_manager;
+ GdkEvent *event;
+ GdkWindow *window;
+
+ if (current_context)
+ g_object_unref (current_context);
+
+ current_context = g_object_new (GDK_TYPE_QUARTZ_DRAG_CONTEXT, NULL);
+ update_context_from_dragging_info (sender);
+
+ window = [[self contentView] gdkWindow];
+
+ device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
+ gdk_drag_context_set_device (current_context,
+ gdk_device_manager_get_client_pointer (device_manager));
+
+ event = gdk_event_new (GDK_DRAG_ENTER);
+ event->dnd.window = g_object_ref (window);
+ event->dnd.send_event = FALSE;
+ event->dnd.context = g_object_ref (current_context);
+ event->dnd.time = GDK_CURRENT_TIME;
+
+ gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
+
+ _gdk_event_emit (event);
+
+ gdk_event_free (event);
+
+ return NSDragOperationNone;
+}
+
+- (void)draggingEnded:(id <NSDraggingInfo>)sender
+{
+ /* leave a note for the source about what action was taken */
+ if (_gdk_quartz_drag_source_context && current_context)
+ _gdk_quartz_drag_source_context->action = current_context->action;
+
+ if (current_context)
+ g_object_unref (current_context);
+ current_context = NULL;
+}
+
+- (void)draggingExited:(id <NSDraggingInfo>)sender
+{
+ GdkEvent *event;
+
+ event = gdk_event_new (GDK_DRAG_LEAVE);
+ event->dnd.window = g_object_ref ([[self contentView] gdkWindow]);
+ event->dnd.send_event = FALSE;
+ event->dnd.context = g_object_ref (current_context);
+ event->dnd.time = GDK_CURRENT_TIME;
+
+ gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
+
+ _gdk_event_emit (event);
+
+ gdk_event_free (event);
+
+ g_object_unref (current_context);
+ current_context = NULL;
+}
+
+- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
+{
+ NSPoint point = [sender draggingLocation];
+ NSPoint screen_point = [self convertBaseToScreen:point];
+ GdkEvent *event;
+ int gx, gy;
+
+ update_context_from_dragging_info (sender);
+ _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy);
+
+ event = gdk_event_new (GDK_DRAG_MOTION);
+ event->dnd.window = g_object_ref ([[self contentView] gdkWindow]);
+ event->dnd.send_event = FALSE;
+ event->dnd.context = g_object_ref (current_context);
+ event->dnd.time = GDK_CURRENT_TIME;
+ event->dnd.x_root = gx;
+ event->dnd.y_root = gy;
+
+ gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
+
+ _gdk_event_emit (event);
+
+ gdk_event_free (event);
+
+ return drag_action_to_drag_operation (current_context->action);
+}
+
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+ NSPoint point = [sender draggingLocation];
+ NSPoint screen_point = [self convertBaseToScreen:point];
+ GdkEvent *event;
+ int gy, gx;
+
+ update_context_from_dragging_info (sender);
+ _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy);
+
+ event = gdk_event_new (GDK_DROP_START);
+ event->dnd.window = g_object_ref ([[self contentView] gdkWindow]);
+ event->dnd.send_event = FALSE;
+ event->dnd.context = g_object_ref (current_context);
+ event->dnd.time = GDK_CURRENT_TIME;
+ event->dnd.x_root = gx;
+ event->dnd.y_root = gy;
+
+ gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
+
+ _gdk_event_emit (event);
+
+ gdk_event_free (event);
+
+ g_object_unref (current_context);
+ current_context = NULL;
+
+ return YES;
+}
+
+- (BOOL)wantsPeriodicDraggingUpdates
+{
+ return NO;
+}
+
+- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
+{
+ GdkEvent *event;
+
+ g_assert (_gdk_quartz_drag_source_context != NULL);
+
+ event = gdk_event_new (GDK_DROP_FINISHED);
+ event->dnd.window = g_object_ref ([[self contentView] gdkWindow]);
+ event->dnd.send_event = FALSE;
+ event->dnd.context = g_object_ref (_gdk_quartz_drag_source_context);
+
+ gdk_event_set_device (event,
+ gdk_drag_context_get_device (_gdk_quartz_drag_source_context));
+
+ _gdk_event_emit (event);
+
+ gdk_event_free (event);
+
+ g_object_unref (_gdk_quartz_drag_source_context);
+ _gdk_quartz_drag_source_context = NULL;
+}
+
+@end
--- /dev/null
+/* GdkQuartzNSWindow.h
+ *
+ * Copyright (C) 2005-2007 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <AppKit/AppKit.h>
+#import <Foundation/Foundation.h>
+#include <glib.h>
+
+@interface GdkQuartzNSWindow : NSWindow {
+ BOOL inMove;
+ BOOL inShowOrHide;
+
+ /* Manually triggered move/resize (not by the window manager) */
+ BOOL inManualMove;
+ BOOL inManualResize;
+ BOOL inTrackManualResize;
+ NSPoint initialMoveLocation;
+ NSPoint initialResizeLocation;
+ NSRect initialResizeFrame;
+}
+
+-(BOOL)isInMove;
+-(void)beginManualMove;
+-(BOOL)trackManualMove;
+-(void)beginManualResize;
+-(BOOL)trackManualResize;
+-(void)showAndMakeKey:(BOOL)makeKey;
+-(void)hide;
+
+@end
+
+
+
+
+++ /dev/null
-/* GdkQuartzWindow.m
- *
- * Copyright (C) 2005-2007 Imendio AB
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#import "GdkQuartzWindow.h"
-#include "gdkquartzwindow.h"
-#include "gdkdnd-quartz.h"
-#include "gdkprivate-quartz.h"
-
-@implementation GdkQuartzNSWindow
-
--(BOOL)windowShouldClose:(id)sender
-{
- GdkWindow *window = [[self contentView] gdkWindow];
- GdkEvent *event;
-
- event = gdk_event_new (GDK_DELETE);
-
- event->any.window = g_object_ref (window);
- event->any.send_event = FALSE;
-
- _gdk_event_queue_append (gdk_display_get_default (), event);
-
- return NO;
-}
-
--(void)windowWillMiniaturize:(NSNotification *)aNotification
-{
- GdkWindow *window = [[self contentView] gdkWindow];
-
- _gdk_quartz_window_detach_from_parent (window);
-}
-
--(void)windowDidMiniaturize:(NSNotification *)aNotification
-{
- GdkWindow *window = [[self contentView] gdkWindow];
-
- gdk_synthesize_window_state (window, 0,
- GDK_WINDOW_STATE_ICONIFIED);
-}
-
--(void)windowDidDeminiaturize:(NSNotification *)aNotification
-{
- GdkWindow *window = [[self contentView] gdkWindow];
-
- _gdk_quartz_window_attach_to_parent (window);
-
- gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0);
-}
-
--(void)windowDidBecomeKey:(NSNotification *)aNotification
-{
- GdkWindow *window = [[self contentView] gdkWindow];
-
- _gdk_quartz_events_update_focus_window (window, TRUE);
-}
-
--(void)windowDidResignKey:(NSNotification *)aNotification
-{
- GdkWindow *window = [[self contentView] gdkWindow];
-
- _gdk_quartz_events_update_focus_window (window, FALSE);
-}
-
--(void)windowDidBecomeMain:(NSNotification *)aNotification
-{
- GdkWindow *window = [[self contentView] gdkWindow];
-
- if (![self isVisible])
- {
- /* Note: This is a hack needed because for unknown reasons, hidden
- * windows get shown when clicking the dock icon when the application
- * is not already active.
- */
- [self orderOut:nil];
- return;
- }
-
- _gdk_quartz_window_did_become_main (window);
-}
-
--(void)windowDidResignMain:(NSNotification *)aNotification
-{
- GdkWindow *window;
-
- window = [[self contentView] gdkWindow];
- _gdk_quartz_window_did_resign_main (window);
-}
-
-/* Used in combination with NSLeftMouseUp in sendEvent to keep track
- * of when the window is being moved with the mouse.
- */
--(void)windowWillMove:(NSNotification *)aNotification
-{
- inMove = YES;
-}
-
--(void)sendEvent:(NSEvent *)event
-{
- switch ([event type])
- {
- case NSLeftMouseUp:
- inManualMove = NO;
- inManualResize = NO;
- inMove = NO;
- break;
-
- case NSLeftMouseDragged:
- if ([self trackManualMove] || [self trackManualResize])
- return;
- break;
-
- default:
- break;
- }
-
- [super sendEvent:event];
-}
-
--(BOOL)isInMove
-{
- return inMove;
-}
-
--(void)windowDidMove:(NSNotification *)aNotification
-{
- GdkWindow *window = [[self contentView] gdkWindow];
- GdkEvent *event;
-
- _gdk_quartz_window_update_position (window);
-
- /* Synthesize a configure event */
- event = gdk_event_new (GDK_CONFIGURE);
- event->configure.window = g_object_ref (window);
- event->configure.x = window->x;
- event->configure.y = window->y;
- event->configure.width = window->width;
- event->configure.height = window->height;
-
- _gdk_event_queue_append (gdk_display_get_default (), event);
-}
-
--(void)windowDidResize:(NSNotification *)aNotification
-{
- NSRect content_rect = [self contentRectForFrameRect:[self frame]];
- GdkWindow *window = [[self contentView] gdkWindow];
- GdkEvent *event;
-
- window->width = content_rect.size.width;
- window->height = content_rect.size.height;
-
- [[self contentView] setFrame:NSMakeRect (0, 0, window->width, window->height)];
-
- _gdk_window_update_size (window);
-
- /* Synthesize a configure event */
- event = gdk_event_new (GDK_CONFIGURE);
- event->configure.window = g_object_ref (window);
- event->configure.x = window->x;
- event->configure.y = window->y;
- event->configure.width = window->width;
- event->configure.height = window->height;
-
- _gdk_event_queue_append (gdk_display_get_default (), event);
-}
-
--(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen
-{
- self = [super initWithContentRect:contentRect
- styleMask:styleMask
- backing:backingType
- defer:flag
- screen:screen];
-
- [self setAcceptsMouseMovedEvents:YES];
- [self setDelegate:self];
- [self setReleasedWhenClosed:YES];
-
- return self;
-}
-
--(BOOL)canBecomeMainWindow
-{
- GdkWindow *window = [[self contentView] gdkWindow];
- GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
-
- switch (impl->type_hint)
- {
- case GDK_WINDOW_TYPE_HINT_NORMAL:
- case GDK_WINDOW_TYPE_HINT_DIALOG:
- return YES;
-
- case GDK_WINDOW_TYPE_HINT_MENU:
- case GDK_WINDOW_TYPE_HINT_TOOLBAR:
- case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
- case GDK_WINDOW_TYPE_HINT_UTILITY:
- case GDK_WINDOW_TYPE_HINT_DOCK:
- case GDK_WINDOW_TYPE_HINT_DESKTOP:
- case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
- case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
- case GDK_WINDOW_TYPE_HINT_TOOLTIP:
- case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
- case GDK_WINDOW_TYPE_HINT_COMBO:
- case GDK_WINDOW_TYPE_HINT_DND:
- return NO;
- }
-
- return YES;
-}
-
--(BOOL)canBecomeKeyWindow
-{
- GdkWindow *window = [[self contentView] gdkWindow];
- GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
-
- if (!window->accept_focus)
- return NO;
-
- /* Popup windows should not be able to get focused in the window
- * manager sense, it's only handled through grabs.
- */
- if (window->window_type == GDK_WINDOW_TEMP)
- return NO;
-
- switch (impl->type_hint)
- {
- case GDK_WINDOW_TYPE_HINT_NORMAL:
- case GDK_WINDOW_TYPE_HINT_DIALOG:
- case GDK_WINDOW_TYPE_HINT_MENU:
- case GDK_WINDOW_TYPE_HINT_TOOLBAR:
- case GDK_WINDOW_TYPE_HINT_UTILITY:
- case GDK_WINDOW_TYPE_HINT_DOCK:
- case GDK_WINDOW_TYPE_HINT_DESKTOP:
- case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
- case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
- case GDK_WINDOW_TYPE_HINT_COMBO:
- return YES;
-
- case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
- case GDK_WINDOW_TYPE_HINT_TOOLTIP:
- case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
- case GDK_WINDOW_TYPE_HINT_DND:
- return NO;
- }
-
- return YES;
-}
-
-- (void)showAndMakeKey:(BOOL)makeKey
-{
- GdkWindow *window = [[self contentView] gdkWindow];
- GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
-
- inShowOrHide = YES;
-
- if (makeKey)
- [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
- else
- [impl->toplevel orderFront:nil];
-
- inShowOrHide = NO;
-}
-
-- (void)hide
-{
- GdkWindow *window = [[self contentView] gdkWindow];
- GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
-
- inShowOrHide = YES;
- [impl->toplevel orderOut:nil];
- inShowOrHide = NO;
-}
-
-- (BOOL)trackManualMove
-{
- NSPoint currentLocation;
- NSPoint newOrigin;
- NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
- NSRect windowFrame = [self frame];
-
- if (!inManualMove)
- return NO;
-
- currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
- newOrigin.x = currentLocation.x - initialMoveLocation.x;
- newOrigin.y = currentLocation.y - initialMoveLocation.y;
-
- /* Clamp vertical position to below the menu bar. */
- if (newOrigin.y + windowFrame.size.height > screenFrame.origin.y + screenFrame.size.height)
- newOrigin.y = screenFrame.origin.y + screenFrame.size.height - windowFrame.size.height;
-
- [self setFrameOrigin:newOrigin];
-
- return YES;
-}
-
--(void)beginManualMove
-{
- NSRect frame = [self frame];
-
- if (inMove || inManualMove || inManualResize)
- return;
-
- inManualMove = YES;
-
- initialMoveLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
- initialMoveLocation.x -= frame.origin.x;
- initialMoveLocation.y -= frame.origin.y;
-}
-
-- (BOOL)trackManualResize
-{
- NSPoint currentLocation;
- NSRect newFrame;
- float dx, dy;
- NSSize min_size;
-
- if (!inManualResize || inTrackManualResize)
- return NO;
-
- inTrackManualResize = YES;
-
- currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
- currentLocation.x -= initialResizeFrame.origin.x;
- currentLocation.y -= initialResizeFrame.origin.y;
-
- dx = currentLocation.x - initialResizeLocation.x;
- dy = -(currentLocation.y - initialResizeLocation.y);
-
- newFrame = initialResizeFrame;
- newFrame.size.width = initialResizeFrame.size.width + dx;
- newFrame.size.height = initialResizeFrame.size.height + dy;
-
- min_size = [self contentMinSize];
- if (newFrame.size.width < min_size.width)
- newFrame.size.width = min_size.width;
- if (newFrame.size.height < min_size.height)
- newFrame.size.height = min_size.height;
-
- /* We could also apply aspect ratio:
- newFrame.size.height = newFrame.size.width / [self aspectRatio].width * [self aspectRatio].height;
- */
-
- dy = newFrame.size.height - initialResizeFrame.size.height;
-
- newFrame.origin.x = initialResizeFrame.origin.x;
- newFrame.origin.y = initialResizeFrame.origin.y - dy;
-
- [self setFrame:newFrame display:YES];
-
- /* Let the resizing be handled by GTK+. */
- if (g_main_context_pending (NULL))
- g_main_context_iteration (NULL, FALSE);
-
- inTrackManualResize = NO;
-
- return YES;
-}
-
--(void)beginManualResize
-{
- if (inMove || inManualMove || inManualResize)
- return;
-
- inManualResize = YES;
-
- initialResizeFrame = [self frame];
- initialResizeLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
- initialResizeLocation.x -= initialResizeFrame.origin.x;
- initialResizeLocation.y -= initialResizeFrame.origin.y;
-}
-
-
-
-static GdkDragContext *current_context = NULL;
-
-static GdkDragAction
-drag_operation_to_drag_action (NSDragOperation operation)
-{
- GdkDragAction result = 0;
-
- /* GDK and Quartz drag operations do not map 1:1.
- * This mapping represents about the best that we
- * can come up.
- *
- * Note that NSDragOperationPrivate and GDK_ACTION_PRIVATE
- * have almost opposite meanings: the GDK one means that the
- * destination is solely responsible for the action; the Quartz
- * one means that the source and destination will agree
- * privately on the action. NSOperationGeneric is close in meaning
- * to GDK_ACTION_PRIVATE but there is a problem: it will be
- * sent for any ordinary drag, and likely not understood
- * by any intra-widget drag (since the source & dest are the
- * same).
- */
-
- if (operation & NSDragOperationGeneric)
- result |= GDK_ACTION_MOVE;
- if (operation & NSDragOperationCopy)
- result |= GDK_ACTION_COPY;
- if (operation & NSDragOperationMove)
- result |= GDK_ACTION_MOVE;
- if (operation & NSDragOperationLink)
- result |= GDK_ACTION_LINK;
-
- return result;
-}
-
-static NSDragOperation
-drag_action_to_drag_operation (GdkDragAction action)
-{
- NSDragOperation result = 0;
-
- if (action & GDK_ACTION_COPY)
- result |= NSDragOperationCopy;
- if (action & GDK_ACTION_LINK)
- result |= NSDragOperationLink;
- if (action & GDK_ACTION_MOVE)
- result |= NSDragOperationMove;
-
- return result;
-}
-
-static void
-update_context_from_dragging_info (id <NSDraggingInfo> sender)
-{
- g_assert (current_context != NULL);
-
- GDK_QUARTZ_DRAG_CONTEXT (current_context)->dragging_info = sender;
- current_context->suggested_action = drag_operation_to_drag_action ([sender draggingSourceOperationMask]);
- current_context->actions = current_context->suggested_action;
-}
-
-- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
-{
- GdkDeviceManager *device_manager;
- GdkEvent *event;
- GdkWindow *window;
-
- if (current_context)
- g_object_unref (current_context);
-
- current_context = g_object_new (GDK_TYPE_QUARTZ_DRAG_CONTEXT, NULL);
- update_context_from_dragging_info (sender);
-
- window = [[self contentView] gdkWindow];
-
- device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
- gdk_drag_context_set_device (current_context,
- gdk_device_manager_get_client_pointer (device_manager));
-
- event = gdk_event_new (GDK_DRAG_ENTER);
- event->dnd.window = g_object_ref (window);
- event->dnd.send_event = FALSE;
- event->dnd.context = g_object_ref (current_context);
- event->dnd.time = GDK_CURRENT_TIME;
-
- gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
-
- _gdk_event_emit (event);
-
- gdk_event_free (event);
-
- return NSDragOperationNone;
-}
-
-- (void)draggingEnded:(id <NSDraggingInfo>)sender
-{
- /* leave a note for the source about what action was taken */
- if (_gdk_quartz_drag_source_context && current_context)
- _gdk_quartz_drag_source_context->action = current_context->action;
-
- if (current_context)
- g_object_unref (current_context);
- current_context = NULL;
-}
-
-- (void)draggingExited:(id <NSDraggingInfo>)sender
-{
- GdkEvent *event;
-
- event = gdk_event_new (GDK_DRAG_LEAVE);
- event->dnd.window = g_object_ref ([[self contentView] gdkWindow]);
- event->dnd.send_event = FALSE;
- event->dnd.context = g_object_ref (current_context);
- event->dnd.time = GDK_CURRENT_TIME;
-
- gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
-
- _gdk_event_emit (event);
-
- gdk_event_free (event);
-
- g_object_unref (current_context);
- current_context = NULL;
-}
-
-- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
-{
- NSPoint point = [sender draggingLocation];
- NSPoint screen_point = [self convertBaseToScreen:point];
- GdkEvent *event;
- int gx, gy;
-
- update_context_from_dragging_info (sender);
- _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy);
-
- event = gdk_event_new (GDK_DRAG_MOTION);
- event->dnd.window = g_object_ref ([[self contentView] gdkWindow]);
- event->dnd.send_event = FALSE;
- event->dnd.context = g_object_ref (current_context);
- event->dnd.time = GDK_CURRENT_TIME;
- event->dnd.x_root = gx;
- event->dnd.y_root = gy;
-
- gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
-
- _gdk_event_emit (event);
-
- gdk_event_free (event);
-
- return drag_action_to_drag_operation (current_context->action);
-}
-
-- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
-{
- NSPoint point = [sender draggingLocation];
- NSPoint screen_point = [self convertBaseToScreen:point];
- GdkEvent *event;
- int gy, gx;
-
- update_context_from_dragging_info (sender);
- _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy);
-
- event = gdk_event_new (GDK_DROP_START);
- event->dnd.window = g_object_ref ([[self contentView] gdkWindow]);
- event->dnd.send_event = FALSE;
- event->dnd.context = g_object_ref (current_context);
- event->dnd.time = GDK_CURRENT_TIME;
- event->dnd.x_root = gx;
- event->dnd.y_root = gy;
-
- gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
-
- _gdk_event_emit (event);
-
- gdk_event_free (event);
-
- g_object_unref (current_context);
- current_context = NULL;
-
- return YES;
-}
-
-- (BOOL)wantsPeriodicDraggingUpdates
-{
- return NO;
-}
-
-- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
-{
- GdkEvent *event;
-
- g_assert (_gdk_quartz_drag_source_context != NULL);
-
- event = gdk_event_new (GDK_DROP_FINISHED);
- event->dnd.window = g_object_ref ([[self contentView] gdkWindow]);
- event->dnd.send_event = FALSE;
- event->dnd.context = g_object_ref (_gdk_quartz_drag_source_context);
-
- gdk_event_set_device (event,
- gdk_drag_context_get_device (_gdk_quartz_drag_source_context));
-
- _gdk_event_emit (event);
-
- gdk_event_free (event);
-
- g_object_unref (_gdk_quartz_drag_source_context);
- _gdk_quartz_drag_source_context = NULL;
-}
-
-@end
+++ /dev/null
-/* GdkQuartzWindow.h
- *
- * Copyright (C) 2005-2007 Imendio AB
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#import <AppKit/AppKit.h>
-#import <Foundation/Foundation.h>
-#include <glib.h>
-
-@interface GdkQuartzNSWindow : NSWindow {
- BOOL inMove;
- BOOL inShowOrHide;
-
- /* Manually triggered move/resize (not by the window manager) */
- BOOL inManualMove;
- BOOL inManualResize;
- BOOL inTrackManualResize;
- NSPoint initialMoveLocation;
- NSPoint initialResizeLocation;
- NSRect initialResizeFrame;
-}
-
--(BOOL)isInMove;
--(void)beginManualMove;
--(BOOL)trackManualMove;
--(void)beginManualResize;
--(BOOL)trackManualResize;
--(void)showAndMakeKey:(BOOL)makeKey;
--(void)hide;
-
-@end
-
-
-
-
libgdk_quartz_la_SOURCES = \
GdkQuartzView.c \
GdkQuartzView.h \
- GdkQuartzWindow.c \
- GdkQuartzWindow.h \
+ GdkQuartzNSWindow.c \
+ GdkQuartzNSWindow.h \
gdkcursor-quartz.c \
gdkdevice-core-quartz.c \
gdkdevicemanager-core-quartz.c \
#define __GDK_WINDOW_QUARTZ_H__
#import <gdk/quartz/GdkQuartzView.h>
-#import <gdk/quartz/GdkQuartzWindow.h>
+#import <gdk/quartz/GdkQuartzNSWindow.h>
#include "gdk/gdkwindowimpl.h"
G_BEGIN_DECLS